//
//Copyright GX. Yuan
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file net.go
 * @brief Leetcode 剑指Offer 第二版
 * @details 剑指 Offer 30. 包含min函数的栈
 * @author GX. Yuan  any question please send mail to yuanguanxu@qq.com
 * @date 2021-6-28
 * @version V1.0
 * @attention 硬件平台: windows 10 家庭版
 * SDK版本：Go 1.16.5
 * IDE版本：GoLand 2020.2.3
 */

package main

import (
	"fmt"
)

type MinStack struct {
	data     []int
	datahelp []int
}

/** initialize your data structure here. */
func Constructor() MinStack {
	return MinStack{make([]int, 0), make([]int, 0)}
}
func (this *MinStack) Push(x int) {
	this.data = append(this.data, x)
	// 如果栈B 为空，或者 小于栈顶元素，那么入栈
	if len(this.datahelp) == 0 || this.datahelp[len(this.datahelp)-1] >= x {
		this.datahelp = append(this.datahelp, x)
	}
}

// 栈的处理放肆
func (this *MinStack) Pop() {
	if this.datahelp[len(this.datahelp)-1] == this.data[len(this.data)-1] {
		this.datahelp = this.datahelp[:len(this.datahelp)-1] // 删除最上面的那个数值
	}
	this.data = this.data[:len(this.data)-1] // 删除最上面的那个数值
}
func (this *MinStack) Top() int {
	return this.data[len(this.data)-1]
}
func (this *MinStack) Min() int {
	// 这里的处理方式不太好，使用遍历比较好
	if len(this.datahelp) == 0 {
		return this.data[len(this.data)-1]
	}
	return this.datahelp[len(this.datahelp)-1]
}
/**
 * Your MinStack object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Push(x);
 * obj.Pop();
 * param_3 := obj.Top();
 * param_4 := obj.Min();
 */
func main() {
	obj := Constructor()
	obj.Push(2)
	obj.Push(0)
	obj.Push(3)
	obj.Push(0)
	fmt.Println(obj)
	fmt.Println(obj.Min())
	obj.Pop()
	fmt.Println(obj.Min())
	obj.Pop()
	fmt.Println(obj.Min())
	obj.Pop()
	fmt.Println(obj.Min())
}

// 使用辅助栈来帮忙实现栈的的最小元素的处理;
// 战B 永远存储的都是这升序数组的最小值;
// 战B 中存储的是，每一段升序的最小值；每次入栈都是比较每段入栈数据，新入的值和原来的值进行比较，找打最小值;
// 栈B 中，用云存储的都是比较小的值，进行比较过的值;
